<?php
/**
 * @package Waterwheel
 */
/* 
 *  Copyright 2010 Andrew Rickmann
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
require_once(dirname(__FILE__) . '/simpletest/autorun.php');

/**
 *
 * Finds the file the given class name and includes it ready for the class to be instantiated.
 * This is passed to the spl_autoload_register function to automate the process.
 *
 * @param String $classname The name of the class being instantiated.
 */
function application_autoload($classname){
	$path = APPLICATION_PATH . "/../classes" . DIRECTORY_SEPARATOR;
	$file = $path . $classname . '.php';
	if( file_exists($file) ){
		include_once($file);
	}
}

//setup the class autoloader
spl_autoload_register('application_autoload');

define('APPLICATION_PATH' , dirname(__FILE__) );

/**
 * Test of Database Connection
 *
 * @author Andrew Rickmann
 */
class TestofSettings extends UnitTestCase {

    /**
     * D before tests
     */
    function setUp() {

    }

    /**
     * Do after tests
     */
    function tearDown() {
        
    }

    function TestCreteRetrieveRemoveSettingGlobal(){

	$settings = new settings();

	//create settings
	//creating a setting should return its value.
	$this->assertTrue( $settings->set('TestSetting1', '215') == 215 , 'The return value equals the input value' );
	$settings->set('TestSetting2', '216') == 216;

	//get the settings
	$this->assertTrue( $settings->get('TestSetting1') == '215' , 'The retrieved value equals the input value' );
	$this->assertTrue( $settings->get('TestSetting2') == '216' , 'The second retrieved value equals the second input value' );

	//remove the settings
	$settings->remove('TestSetting1');
	$settings->remove('TestSetting2');

	//get the settings that no longer exist
	$this->assertFalse( $settings->get('TestSetting1') , 'The setting no longer exists' );
	$this->assertFalse( $settings->get('TestSetting2') , 'The second setting no longer exists' );

	//check the database is now empty
	$empty_sql = "SELECT count(*) as count FROM `settings`;";
	$this->assertTrue( databaseconnection::queryScalar($empty_sql) === '0' );

    }

    function TestCreateSettingNonGlobal(){

	$settings = new settings();

	//create settings
	//creating a setting should return its value.
	$settings->set('TestSetting1', '215' , 'TestNamespace');
	$settings->set('TestSetting2', '216' , 'TestNamespace');

	//get the settings
	$this->assertTrue( $settings->get('TestSetting1' , 'TestNamespace') == '215' , 'The retrieved value under this namespace equals the input value' );
	$this->assertTrue( $settings->get('TestSetting2' , 'TestNamespace') == '216' , 'The second retrieved value under this namespace equals the input value' );

	//remove the settings
	$settings->remove('TestSetting1' , 'TestNamespace');
	$settings->remove('TestSetting2' , 'TestNamespace');

	//get the settings that no longer exist
	$this->assertFalse( $settings->get('TestSetting1' , 'TestNamespace') , 'The setting no longer exists' );
	$this->assertFalse( $settings->get('TestSetting2' , 'TestNamespace') , 'The second settng no longer exists' );

    }

    function TestUpdateSettingGlobal(){

	$settings = new settings();

	//create the setting
	$settings->set('TestSetting1', '215');
	//update it with a different number
	$settings->set('TestSetting1', '216');

	//check the value is the new vlaue
	$this->assertTrue( $settings->get('TestSetting1') == '216' , 'The returned value equals the updated value' );

	//remove the setting
	$settings->remove('TestSetting1');


    }

    function TestUpdateSettingNonGlobal(){

	$settings = new settings();

	//create the setting
	$settings->set('TestSetting1', '215' , 'TestNamespace');
	//update it with a different number
	$settings->set('TestSetting1', '216' , 'TestNamespace');

	//check the value is the new vlaue
	$this->assertTrue( $settings->get('TestSetting1' , 'TestNamespace') == '216' , 'The return value equals the update value' );

	//remove the setting
	$settings->remove('TestSetting1' , 'TestNamespace');


    }

    //the other 'get' functions rely on get namespace
    //so test this first
    function TestGetNameSpace(){

	$settings = new settings();

	//create the setting
	$settings->set('TestSetting1', '215' , 'TestNamespace1');
	$settings->set('TestSetting1', '216' , 'TestNamespace2');
	$settings->set('TestSetting1', '217' , 'TestNamespace3');
	$settings->set('TestSetting1', '218' , 'TestNamespace4');

	//get the names
	$ns1 = $settings->get_namespace('TestNamespace1');

	//check it is an array
	$this->assertTrue(is_array($ns1) , 'Check the namespace returned is an array');

	$this->assertTrue( isset($ns1['TestSetting1']) , 'The namespace array contains the setting key' );

	if ( isset( $ns1['TestSetting1'] ) && $ns1['TestSetting1'] == '215'  ){
	    $this->pass('The setting value is correct.');
	} else {
	    $this->fail('The setting value is incorrect or not set.');
	}

	//remove the settings again
	$settings->remove('TestSetting1' , 'TestNamespace1');
	$settings->remove('TestSetting1' , 'TestNamespace2');
	$settings->remove('TestSetting1' , 'TestNamespace3');
	$settings->remove('TestSetting1' , 'TestNamespace4');

    }

    function TestRemoveSettingsGlobal(){

	//this is an alias of the remove namespace method which checks for
	//a preset namespace, therefore we can check this without
	//the need to check removenamespace.

	//the global namespace is protected and so it should not be possible to
	//remove every setting

	$settings = new settings();

	$settings->set('globalTestSetting1' , 1);
	$settings->set('globalTestSetting2' , 2);
	$settings->set('globalTestSetting3' , 3);
	$settings->set('globalTestSetting4' , 4);

	$this->assertFalse( $settings->remove_settings('global') , 'Removal of global namespace settings should fail');

	//make sure
	$this->assertTrue( $settings->get('globalTestSetting1') == 1 , 'Setting still exists and returns the correct value' );

	//remove settings individually
	$settings->remove('GlobalTestSetting1');
	$settings->remove('GlobalTestSetting2');
	$settings->remove('GlobalTestSetting3');
	$settings->remove('GlobalTestSetting4');

    }

    function TestRemoveSettingsNonGlobal(){

	//this is an alias of the remove namespace method which checks for
	//a preset namespace, therefore we can check this without
	//the need to check removenamespace.

	//the global namespace is protected and so it should not be possible to
	//remove every setting

	$settings = new settings();

	$settings->set('globalTestSetting1' , 1 , 'TestNamespace');
	$settings->set('globalTestSetting2' , 2 , 'TestNamespace');
	$settings->set('globalTestSetting3' , 3 , 'TestNamespace');
	$settings->set('globalTestSetting4' , 4 , 'TestNamespace');

	$this->assertTrue( $settings->remove_settings('TestNamespace') , 'Removal of TestNamespace namespace settings return true');

	//make sure
	$this->assertFalse( $settings->get('globalTestSetting1' , 'TestNamespace') , 'Setting 1 no longer exists' );
	$this->assertFalse( $settings->get('globalTestSetting2' , 'TestNamespace') , 'Setting 2 no longer exists' );
	$this->assertFalse( $settings->get('globalTestSetting3' , 'TestNamespace') , 'Setting 3 no longer exists' );
	$this->assertFalse( $settings->get('globalTestSetting4' , 'TestNamespace') , 'Setting 4 no longer exists' );

    }

    function TestUseNamespace(){

	//test all functions using a instance namespace
	$settings = new settings();
	$settings->use_namespace('TestInstanceNamespace');

	//create a setting
	$settings->set('TestSetting1', 1);

	//try and get it without specifying a namespace
	$this->assertTrue( $settings->get('TestSetting1') === 1 , 'Value returned is appropriate' );
	//check it cannot be got from global
	$this->assertFalse( $settings->get('TestSetting1' , 'global') , 'Setting does not exist in global namespace' );
	//check it can be got by specifying the namspace
	$this->assertTrue( $settings->get('TestSetting1' , 'TestInstanceNamespace' ) === 1 , 'Value returned from the correct namespace is correct' );

	//remove the setting
	$settings->remove('TestSetting1');

	//check it no longer exists normally
	$this->assertFalse( $settings->get('TestSetting1') , 'Setting does not exist if no namespace is specifgied' );
	//check it no longer exists if called with the namespace
	$this->assertFalse( $settings->get('TestSetting1' , 'TestInstanceNamespace') , 'Setting does not exist in specified namespace' );

	//create a few setting and then remove them all
	$settings->set('TestSetting1', 1);
	$settings->set('TestSetting2', 2);
	$settings->set('TestSetting3', 3);
	$settings->set('TestSetting4', 4);

	$settings->remove_settings();

	$this->assertFalse( $settings->get('TestSetting1') , 'Setting does not exist if no namespace is specifgied' );
	$this->assertFalse( $settings->get('TestSetting2') , 'Setting does not exist if no namespace is specifgied' );
	$this->assertFalse( $settings->get('TestSetting3') , 'Setting does not exist if no namespace is specifgied' );
	$this->assertFalse( $settings->get('TestSetting4') , 'Setting does not exist if no namespace is specifgied' );

	$this->assertFalse( $settings->get('TestSetting1' , 'TestInstanceNamespace') , 'Setting does not exist in specified namespace' );
	$this->assertFalse( $settings->get('TestSetting2' , 'TestInstanceNamespace') , 'Setting does not exist in specified namespace' );
	$this->assertFalse( $settings->get('TestSetting3' , 'TestInstanceNamespace') , 'Setting does not exist in specified namespace' );
	$this->assertFalse( $settings->get('TestSetting4' , 'TestInstanceNamespace') , 'Setting does not exist in specified namespace' );


    }


}

?>